package com.geek.dubbo.study.consumer;


import com.geek.dubbo.study.common.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static java.lang.String.format;

public class Consumer {
  public static void main(String[] args) {
    //Prevent to get IPV6 address,this way only work in debug mode
    //But you can pass use -Djava.net.preferIPv4Stack=true,then it work well whether in debug mode or not
    System.setProperty("java.net.preferIPv4Stack", "true");
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
    context.start();
    final DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy

    AtomicInteger term = new AtomicInteger(0);
    int count = 4;
    CyclicBarrier startBarrier = new CyclicBarrier(count, () -> {
      System.out.println(format("\n****第%d轮调用开始****", term.get()));
    });
    CyclicBarrier endBarrier = new CyclicBarrier(count, () -> {
      System.out.println(format("****第%d轮调用结束****\n", term.getAndIncrement()));
    });
    for (int i = 0; i < count; i++) {
      Thread task = new Thread(() -> {
        while (true) {
          try {
            startBarrier.await();
            TimeUnit.SECONDS.sleep(3);
            String hello = demoService.sayHello("world"); // call remote method
            System.out.println(format("%s %s调用成功，返回：%s", new Date(), Thread.currentThread().getName(), hello));
          } catch (Throwable throwable) {
            System.out.println(format("%s %s调用失败，失败原因：%s", new Date(), Thread.currentThread().getName(), throwable.getMessage().split("\n")[0]));
          } finally {
            try {
              TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(100));
              endBarrier.await();
            } catch (InterruptedException e) {
              e.printStackTrace();
            } catch (BrokenBarrierException e) {
              e.printStackTrace();
            }
          }
        }
      });
      task.setName(format("task-%d", i));
      task.start();

    }

    try {
      System.in.read();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
